const config = require('../config/config')
const { genRandomStr, xml2js } = require('../utils/util')
const queryStr = require('querystring');
const crypto = require('crypto');
const convert = require('xml-js')
const rawbody = require('raw-body')
const contentType = require('content-type')
const qrcode = require('qrcode')
const io = require('../utils/socketio')
const { post } = require('../utils/http')
const log = require('../utils/log')


var client = null;
io.on('connection', (curClient) => {
  console.log('koa connection ...')
  client = curClient;
})

class Payment {

  //获取签名
  _genSign(params) {

    delete params['sign']

    for (let o in params) {
      if (!params[o]) {
        delete params[o]
      }
    }

    var result = Object.keys(params).sort().reduce((obj, key) => {
      obj[key] = params[key];
      return obj;
    }, {})



    let stringA = queryStr.stringify(result, null, null, {
      encodeURIComponent: (val) => {
        return queryStr.unescape(val);
      }
    });

    console.log('stringA:', stringA)

    let stringSignTemp = stringA + '&key=' + config.key;
    log.debug('stringSignTemp:', stringSignTemp)

    let sign = crypto.createHash('md5').update(stringSignTemp).digest('hex').toUpperCase()

    return sign;

  }

  //生成支付二维码
  async getQRCode(ctx) {
    //公众号id
    let appid = config.appid;
    //商户号
    let mch_id = config.mch_id;
    //随机字符串
    let nonce_str = genRandomStr(32);

    //商品的描述
    let body = '一瓶可乐'
    //商户的订单号
    let out_trade_no = '20200519003';
    //商品的金额
    let total_fee = 1;
    //终端ip
    let spbill_create_ip = '127.0.0.1'
    //通知地址
    let notify_url = 'https://www.web678.xyz/api/notify'
    //交易类型
    let trade_type = 'NATIVE'

    let params = {
      appid,
      mch_id,
      nonce_str,
      body,
      out_trade_no,
      total_fee,
      spbill_create_ip,
      notify_url,
      trade_type
    }

    //签名
    let sign = this._genSign(params);

    let json = {
      xml: {
        sign,
        ...params
      }
    }

    let xml = convert.json2xml(json, {
      compact: true
    });

    let result = await post(config.url, xml);
    let obj = xml2js(result.data);
    console.log('obj:', obj)
    if (obj.result_code === 'SUCCESS') {
      let imgData = await qrcode.toDataURL(obj.code_url);
      await ctx.render('qrcode', {
        qrcode: imgData
      })
    } else {
      ctx.body = obj.err_code_des;
    }
  }

  async notify(ctx) {
    log.debug('支付回调接口');
    let rawXml = await rawbody(ctx.req, {
      length: ctx.req.headers['content-length'],
      limit: '1mb',
      encoding: contentType.parse(ctx.req).parameters.charset
    })
    log.debug('rawXml:', rawXml.toString());
    let obj = xml2js(rawXml)
    let orignSign = obj.sign;
    //查询商户后台数据库，根据订单id,验证费用和其它信息
    //...
    let sign = this._genSign(obj)
    log.debug('orignSign:' + orignSign);
    log.debug('sign:' + sign)
    if (orignSign === sign) {
      if (obj.result_code === 'SUCCESS') {
        client.emit('msg', '支付成功')
        ctx.body = `
        <xml>
          <return_code><![CDATA[SUCCESS]]></return_code>
          <return_msg><![CDATA[OK]]></return_msg>
        </xml>
        `
      } else {
        client.emit('msg', '支付失败')
        ctx.body = `
        <xml>
          <return_code><![CDATA[FAIL]]></return_code>
          <return_msg><![CDATA[OK]]></return_msg>
        </xml>
        `
      }
    } else {
      client.emit('msg', '支付失败')
      ctx.body = `
        <xml>
          <return_code><![CDATA[FAIL]]></return_code>
          <return_msg><![CDATA[OK]]></return_msg>
        </xml>
        `
    }

  }
}

module.exports = new Payment();